using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;

public class AgvCargoTriggerComponent : IAgvCargoTrigger
{
    public Transform TouchCollider;
    public int CarriedCargoWaitingTimeToHide, CarriedCargoWaitingTimeToShow;
    public Action<Transform> OnTouchedCargoAppear, OnTouchedCargoDisappear;

    protected Transform CarriedCargo;

    protected Transform touchedCargoContainer;

    [SerializeField]
    string touchedCargoTag = TagName.cargoContainer;

    //int activeTouchedCargoInChild;
    int CargoTypeIndex;
    string activeTouchedCargoTag;

    bool isTouching = false;

    LoadedModel m_Loaded;
    public AgvCargoTriggerComponent(Transform collider)
    {
        TouchCollider = collider;
        CarriedCargo = TouchCollider;
        m_Loaded = new();
        m_Loaded.OnContentChange += OnLoadStateChanged;
    }
    public AgvCargoTriggerComponent(Transform collider, string triggerTag)
    {
        TouchCollider = collider;
        CarriedCargo = TouchCollider;
        touchedCargoTag = triggerTag;
        m_Loaded = new();
        m_Loaded.OnContentChange += OnLoadStateChanged;

        OnTouchedCargoAppear += (target) =>
        {
            target.gameObject.SetActive(true);
        };
        OnTouchedCargoDisappear += (target) =>
        {
            target.gameObject.SetActive(false);
        };
    }
    ~AgvCargoTriggerComponent()
    {
        m_Loaded.OnContentChange -= OnLoadStateChanged;
    }
    public virtual void Update(bool loaded)
    {
        m_Loaded.Loaded = loaded;
    }

    public void OnLoadStateChanged(bool result)
    {
        if (result == true)
        {
            PickCargo();
        }
        else
        {
            PutCargo();
        }
    }

    public void CarriedCargoAppear()
    {
        for (int i = 0; i < CarriedCargo.childCount; i++)
        {
            if (CarriedCargo.GetChild(i).CompareTag(activeTouchedCargoTag))
            {
                CarriedCargo.GetChild(i).gameObject.SetActive(true);
            }
        }
        //CarriedCargo.GetChild(activeTouchedCargoInChild).gameObject.SetActive(true);
        //TouchedCargoDisappear();
    }

    public void CarriedCargoDisappear()
    {
        for (int i = 0; i < CarriedCargo.childCount; i++)
        {
            if (CarriedCargo.GetChild(i).CompareTag(activeTouchedCargoTag))
            {
                CarriedCargo.GetChild(i).gameObject.SetActive(false);
            }
        }
        //ChangeTargetActive(CarriedCargo.GetChild(activeTouchedCargoInChild), false);

        //TouchedCargoAppear();
    }

    public async void PickCargo()
    {
        await UniTask.Delay(System.TimeSpan.FromSeconds(CarriedCargoWaitingTimeToShow));

        CarriedCargoAppear();
        /*for(int i =0; i < CarriedCargo.childCount; i++)
        {
            if (CarriedCargo.GetChild(i).CompareTag(activeTouchedCargoTag))
            {
                CarriedCargo.GetChild(i).gameObject.SetActive(true);
            }
        }*/
        //CarriedCargo.GetChild(activeTouchedCargoInChild).gameObject.SetActive(true);
        TouchedCargoDisappear();
    }

    public async void PutCargo()
    {
        await UniTask.Delay(System.TimeSpan.FromSeconds(CarriedCargoWaitingTimeToHide));

        CarriedCargoDisappear();
        /*for (int i = 0; i < CarriedCargo.childCount; i++)
        {
            if (CarriedCargo.GetChild(i).CompareTag(activeTouchedCargoTag))
            {
                CarriedCargo.GetChild(i).gameObject.SetActive(false);
            }
        }*/
        //ChangeTargetActive(CarriedCargo.GetChild(activeTouchedCargoInChild)/*CarriedCargo*/, false);

        TouchedCargoAppear();
    }

    public void TouchedCargoAppear()
    {
        TouchedCargoFromHideToActive();
    }
    private void TouchedCargoFromHideToActive()
    {
        if (touchedCargoContainer != null)
        {
            for(int i = 0; i< touchedCargoContainer.childCount; i++)
            {
                if (touchedCargoContainer.GetChild(i).CompareTag(activeTouchedCargoTag))
                {
                    OnTouchedCargoAppear?.Invoke(touchedCargoContainer.GetChild(i));
                    break;
                    //ChangeTargetActive(touchedCargo.GetChild(i), true);
                }
            }
        }
            //ChangeTargetActive(touchedCargo.GetChild(activeTouchedCargoInChild), true);
    }

    public void TouchedCargoDisappear()
    {
        TouchedCargoFromActiveToHide();
    }
    private void TouchedCargoFromActiveToHide()
    {
        //await UniTask.WaitUntil(() => isTouching == true);

        if (touchedCargoContainer != null)
        {
            for (int i = 0; i < touchedCargoContainer.childCount; i++)
            {
                if (touchedCargoContainer.GetChild(i).CompareTag(activeTouchedCargoTag))
                {
                    OnTouchedCargoDisappear?.Invoke(touchedCargoContainer.GetChild(i));
                    break;
                    //ChangeTargetActive(touchedCargo.GetChild(i), false);
                }
            }
        }
            //ChangeTargetActive(touchedCargo.GetChild(activeTouchedCargoInChild), false);

        //await UniTask.WaitUntil(() => isTouching == false);
    }

    public Transform GetTouchedCargo(Transform targetCargo)
    {
        if (targetCargo.CompareTag(touchedCargoTag))
        {
            Debug.Log($"Touched Cargo = {targetCargo}");
            touchedCargoContainer = targetCargo;
            CheckCargoActive(targetCargo);
            isTouching = true;
            return touchedCargoContainer;
        }
        return null;
    }

    private void CheckCargoActive(Transform touchedCargo)
    {
        for (int i = 0; i < touchedCargo.childCount; i++)
        {
            if (
                //touchedCargo.GetChild(i).childCount > 0 && touchedCargo.GetChild(i).GetChild(0).gameObject.activeInHierarchy
                touchedCargo.GetChild(i).gameObject.activeInHierarchy
                )
            {
                CargoTypeIndex = i;
                //activeTouchedCargoInChild = i;
                activeTouchedCargoTag = touchedCargo.GetChild(i).tag;
            }
        }
        //throw new NotImplementedException();
    }
    /*public void SetActiveTouchedCargoInChild(int cargoTypeIndex)
    {
        activeTouchedCargoInChild = cargoTypeIndex;
    }*/
    public void SetActiveTouchedCargoTag(string cargoTag)
    {
        activeTouchedCargoTag = cargoTag;
    }

    private void ChangeTargetActive(Transform target, bool isActive)
    {
        target.gameObject.SetActive(isActive);
    }
    public Transform LeaveTouchedCargo(Transform touchedCargo)
    {

        if (this.touchedCargoContainer == touchedCargo)
        {
            this.touchedCargoContainer = null;
            isTouching = false;
            return null;
        }
        return this.touchedCargoContainer;
    }
    public void SetLoadedValueWithoutEvent(bool newValue)
    {
        m_Loaded.SetValueWithoutEvent(newValue);
    }
    public class LoadedModel
    {
        private bool loaded;

        public bool Loaded
        {
            get
            {
                return loaded;
            }
            set
            {
                if (value != loaded)
                {
                    loaded = value;
                    OnContentChange?.Invoke(loaded);
                }
            }
        }

        public Action<bool> OnContentChange;
        public void SetValueWithoutEvent(bool newValue) => loaded = newValue;
    }
}
